package com.hxzf.mvp.commons;

import com.hxzf.mvp.commons.annotation.ErrorCode;
import com.hxzf.mvp.commons.constant.RespCode;
import com.hxzf.mvp.commons.domain.PageData;
import com.hxzf.mvp.commons.domain.Resp;
import com.hxzf.mvp.commons.tool.Dates;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import javax.validation.groups.Default;
import java.beans.PropertyEditorSupport;
import java.util.Date;
import java.util.List;

/**
 * 视图层基类
 *
 * <p>所有RestController强制继承。
 *
 * <p>关于数据校验：
 * <p>基础数据校验使用JSR 303注解自动完成，通过{@link ErrorCode}注解可以返回指定错误码；
 * <p>Controller业务逻辑校验结果应该通过{@code fail()}方法尽早返回；
 * <p>Service层的校验错误直接抛出{@link BusinessException}即可。
 *
 * @author Kai
 */
@Validated(Default.class)
public abstract class BaseController {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                this.setValue(Dates.parseDate(text));
            }
        });
    }

    public <T> Resp<T> ok() {
        return ok(RespCode.SUCCESS.getMessage());
    }

    public <T> Resp<T> ok(T data) {
        return new Resp<>(RespCode.SUCCESS.getCode(), RespCode.SUCCESS.getMessage(), data);
    }

    public <T> Resp<T> ok(String msg) {
        return new Resp<>(RespCode.SUCCESS.getCode(), msg);
    }

    public <T> Resp<T> ok(boolean result) {
        return result ? ok() : fail();
    }

    public <T> Resp<T> fail() {
        return new Resp<>(RespCode.FAIL.getCode(), RespCode.INTERNAL_SERVER_ERROR.getMessage());
    }

    public <T> Resp<T> fail(int code) {
        return new Resp<>(code, RespCode.INTERNAL_SERVER_ERROR.getMessage());
    }

    public <T> Resp<T> fail(String msg) {
        return new Resp<>(RespCode.FAIL.getCode(), msg);
    }

    public <T> Resp<T> fail(RespCode respCode) {
        return new Resp<>(respCode.getCode(), respCode.getMessage());
    }

    public <T> PageData<T> page(List<T> data) {
        return new PageData<>(data);
    }
}